package com.swanclouds.redfish.systems.domain.Oem.BMC;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.swanclouds.model.systems.builder.Oem.BMC.BMCCreateVolume;
import com.swanclouds.model.systems.builder.Oem.BMC.BMCCreateVolumeBuilder;

import java.util.List;

/**
 * OEM.BMC 创建逻辑卷
 *
 * @author 张立强
 */
public class BMCCreateVolumeConcrete implements BMCCreateVolume {

    @JsonProperty("VolumeName")
    private String volumeName;

    @JsonProperty("Drives")
    private List<String> drives;

    @JsonProperty("VolumeRaidLevel")
    private String volumeRaidLevel;

    @JsonProperty("SpanNumber")
    private Integer spanNumber = 1;

    @JsonProperty("CapacityBytes")
    private Long capacityBytes;

    @JsonProperty("DefaultReadPolicy")
    private DefaultReadPolicy defaultReadPolicy;

    @JsonProperty("DefaultWritePolicy")
    private DefaultWritePolicy defaultWritePolicy;

    @JsonProperty("DefaultCachePolicy")
    private DefaultCachePolicy defaultCachePolicy;

    @JsonProperty("AccessPolicy")
    private AccessPolicy accessPolicy;

    @JsonProperty("DriveCachePolicy")
    private DriveCachePolicy driveCachePolicy;

    @JsonProperty("InitializationMode")
    private InitializationMode initializationMode;

    @JsonProperty("OptimumIOSizeBytes")
    private Integer optimumIOSizeBytes;

    /**
     * 逻辑盘的名称 最大长度为15个字节的字符串
     *
     * @return volumeName
     */
    @Override
    public String getVolumeName() {
        return this.volumeName;
    }

    /**
     * 物理成员盘列表
     *
     * @return drives
     */
    @Override
    public List<String> getDrives() {
        return this.drives;
    }

    /**
     * 逻辑盘的RAID级别 [RAID0,RAID1,RAID2,RAID5,RAID10,RAID020...]
     *
     * @return volumeRaidLevel
     */
    @Override
    public String getVolumeRaidLevel() {
        return this.volumeRaidLevel;
    }

    /**
     * 逻辑盘子组个数
     *
     * @return spanNumber
     */
    @Override
    public Integer getSpanNumber() {
        return this.spanNumber;
    }

    /**
     * 逻辑盘容量 整数，单位为字节
     *
     * @return capacityBytes
     */
    @Override
    public Long getCapacityBytes() {
        return this.capacityBytes;
    }

    /**
     * 逻辑盘默认读策略 [No Read Ahead, Read Ahead]
     *
     * @return defaultReadPolicy
     */
    @Override
    public String getDefaultReadPolicy() {
        return this.defaultReadPolicy.getValue();
    }

    /**
     * 逻辑盘默认写策略 [Write Through, Write Back, Write Back Always]
     *
     * @return defaultWritePolicy
     */
    @Override
    public String getDefaultWritePolicy() {
        return this.defaultWritePolicy.getValue();
    }

    /**
     * 逻辑盘默认的Cache策略 [Direct IO, Cache IO]
     *
     * @return defaultCachePolicy
     */
    @Override
    public String getDefaultCachePolicy() {
        return this.defaultCachePolicy.getValue();
    }

    /**
     * 逻辑盘的访问策略 [Read/Write, Read Only, Blocked]
     *
     * @return accessPolicy
     */
    @Override
    public String getAccessPolicy() {
        return this.accessPolicy.getValue();
    }

    /**
     * 物理成员盘的缓存策略 [Unchanged, Enabled, Disabled]
     *
     * @return driveCachePolicy
     */
    @Override
    public String getDriveCachePolicy() {
        return this.driveCachePolicy.getValue();
    }

    /**
     * 逻辑盘初始化模式 [No Initialization, Quick Initialization, Full Initialization]
     *
     * @return initializationMode
     */
    @Override
    public String getInitializationMode() {
        return this.initializationMode.getValue();
    }

    /**
     * 逻辑盘条带大小 整数，单位为字节
     *
     * @return optimumIOSizeBytes
     */
    @Override
    public Integer getOptimumIOSizeBytes() {
        return this.optimumIOSizeBytes;
    }

    public enum DefaultReadPolicy {
        NoReadAhead("NoReadAhead","No Read Ahead"),
        ReadAhead("ReadAhead","Read Ahead");

        private String type;
        private String value;

        DefaultReadPolicy(String type, String value) {
            this.type = type;
            this.value = value;
        }

        public String getType() {
            return type;
        }

        public String getValue() {
            return value;
        }

        public static String getValueByType(String type) {
            for (DefaultReadPolicy policy : values()) {
                if (policy.getType().equals(type)) {
                    return policy.getValue();
                }
            }
            return DefaultReadPolicy.ReadAhead.getValue();
        }
    }
    public enum DefaultWritePolicy {
        WriteThrough("WriteThrough","Write Through"),
        WriteBack("WriteBack","Write Back"),
        WriteBackAlways("WriteBackAlways","Write Back Always");

        private String type;
        private String value;

        DefaultWritePolicy(String type, String value) {
            this.type = type;
            this.value = value;
        }

        public String getType() {
            return type;
        }

        public String getValue() {
            return value;
        }

        public static String getValueByType(String type) {
            for (DefaultWritePolicy policy : values()) {
                if (policy.getType().equals(type)) {
                    return policy.getValue();
                }
            }
            return DefaultWritePolicy.WriteBack.getValue();
        }
    }
    public enum DefaultCachePolicy {
        DirectIO("DirectIO","Direct IO"),
        CacheIO("CacheIO","Cache IO");


        private String type;
        private String value;

        DefaultCachePolicy(String type, String value) {
            this.type = type;
            this.value = value;
        }

        public String getType() {
            return type;
        }

        public String getValue() {
            return value;
        }

        public static String getValueByType(String type) {
            for (DefaultCachePolicy policy : values()) {
                if (policy.getType().equals(type)) {
                    return policy.getValue();
                }
            }
            return DefaultCachePolicy.CacheIO.getValue();
        }
    }
    public enum AccessPolicy {
        Read_Write("Read_Write","Read/Write"),
        ReadOnly("ReadOnly","Read Only"),
        Blocked("Blocked","Blocked");

        private String type;
        private String value;

        AccessPolicy(String type, String value) {
            this.type = type;
            this.value = value;
        }

        public String getType() {
            return type;
        }

        public String getValue() {
            return value;
        }

        public static String getValueByType(String type) {
            for (AccessPolicy policy : values()) {
                if (policy.getType().equals(type)) {
                    return policy.getValue();
                }
            }
            return AccessPolicy.Read_Write.getValue();
        }
    }
    public enum DriveCachePolicy {
        Unchanged("Unchanged","Unchanged"),
        Enabled("Enabled","Enabled"),
        Disabled("Disabled","Disabled");

        private String type;
        private String value;

        DriveCachePolicy(String type, String value) {
            this.type = type;
            this.value = value;
        }

        public String getType() {
            return type;
        }

        public String getValue() {
            return value;
        }

        public static String getValueByType(String type) {
            for (DriveCachePolicy policy : values()) {
                if (policy.getType().equals(type)) {
                    return policy.getValue();
                }
            }
            return DriveCachePolicy.Unchanged.getValue();
        }
    }
    public enum InitializationMode {
        No("No","No Initialization"),
        Quick("Quick","Quick Initialization"),
        Full("Full","Full Initialization");

        private String type;
        private String value;

        InitializationMode(String type, String value) {
            this.type = type;
            this.value = value;
        }

        public String getType() {
            return type;
        }

        public String getValue() {
            return value;
        }

        public static String getValueByType(String type) {
            for (InitializationMode policy : values()) {
                if (policy.getType().equals(type)) {
                    return policy.getValue();
                }
            }
            return InitializationMode.Quick.getValue();
        }
    }

    @Override
    public BMCCreateVolumeBuilder toBuilder() {
        return BMCCreateVolumeConcrete.builder();
    }

    public static BMCCreateVolumeBuilder builder() {
        return new BMCCreateConcreteVolumeBuilder();
    }

    public static class BMCCreateConcreteVolumeBuilder implements BMCCreateVolumeBuilder {

        BMCCreateVolumeConcrete m;

        BMCCreateConcreteVolumeBuilder() {
            this(new BMCCreateVolumeConcrete());
        }

        BMCCreateConcreteVolumeBuilder(BMCCreateVolumeConcrete m) {
            this.m = m;
        }

        @Override
        public BMCCreateVolumeBuilder volumeName(String volumeName) {
            m.volumeName = volumeName;
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder drives(List<String> drives) {
            m.drives = drives;
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder addDrive(String drive) {
            if (drive == null) {
                return this;
            }
            if (m.drives == null) {
                m.drives = Lists.newArrayList();
            }
            m.drives.add(drive);
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder volumeRaidLeve(String volumeRaidLeve) {
            m.volumeRaidLevel = volumeRaidLeve;
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder spanNumber(Integer spanNumber) {
            m.spanNumber = spanNumber;
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder capacityBytes(Long capacityBytes) {
            m.capacityBytes = capacityBytes;
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder DefaultReadPolicy(String defaultReadPolicy) {
            m.defaultReadPolicy = DefaultReadPolicy.valueOf(defaultReadPolicy);
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder DefaultWritePolicy(String defaultWritePolicy) {
            m.defaultWritePolicy = DefaultWritePolicy.valueOf(defaultWritePolicy);
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder DefaultCachePolicy(String defaultCachePolicy) {
            m.defaultCachePolicy = DefaultCachePolicy.valueOf(defaultCachePolicy);
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder AccessPolicy(String accessPolicy) {
            m.accessPolicy = AccessPolicy.valueOf(accessPolicy);
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder DriveCachePolicy(String driveCachePolicy) {
            m.driveCachePolicy = DriveCachePolicy.valueOf(driveCachePolicy);
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder InitializationMode(String initializationMode) {
            m.initializationMode = InitializationMode.valueOf(initializationMode);
            return this;
        }

        @Override
        public BMCCreateVolumeBuilder OptimumIOSizeBytes(Integer optimumIOSizeBytes) {
            m.optimumIOSizeBytes = optimumIOSizeBytes;
            return this;
        }

        /**
         * Creates and return the Model Entity M
         *
         * @return M instance
         */
        @Override
        public BMCCreateVolume build() {
            return m;
        }

        /**
         * Creates a Builder using the param M as the default values
         *
         * @param in The M
         * @return Builder
         */
        @Override
        public BMCCreateVolumeBuilder from(BMCCreateVolume in) {
            m = (BMCCreateVolumeConcrete) in;
            return this;
        }

        @Override
        public String toString() {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                return objectMapper.writeValueAsString(this);
            } catch (JsonProcessingException e) {
            }
            return "HuaWeiCreateConcreteVolumeBuilder {" +
                    "m=" + m +
                    '}';
        }
    }

    @Override
    public String toString() {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.writeValueAsString(this);
        } catch (JsonProcessingException e) {
        }
        return "BMCCreateVolumeConcrete {" +
                "volumeName='" + volumeName + '\'' +
                ", drives=" + drives +
                ", volumeRaidLevel='" + volumeRaidLevel + '\'' +
                ", spanNumber=" + spanNumber +
                ", capacityBytes=" + capacityBytes +
                ", defaultReadPolicy=" + defaultReadPolicy.getValue() +
                ", defaultWritePolicy=" + defaultWritePolicy.getValue() +
                ", defaultCachePolicy=" + defaultCachePolicy.getValue() +
                ", accessPolicy=" + accessPolicy.getValue() +
                ", driveCachePolicy=" + driveCachePolicy.getValue() +
                ", initializationMode=" + initializationMode.getValue() +
                ", optimumIOSizeBytes=" + optimumIOSizeBytes +
                '}';
    }
}
